﻿using System;
using System.Net;
using System.Windows.Input;
using Automation;
using Automation.Modbus.Tag;
using Demo.Helpers;

namespace Demo
{
    public class WaterTankViewModel : NotifyPropertyChanged
    {
        #region Fields
        private IPAddress _IP = new IPAddress(new byte[] { 127, 0, 0, 1 });
        private Boolean _Connected;
        #endregion

        #region Constructor(s)
        public WaterTankViewModel()
        {
            Initialize();
        }
        #endregion

        #region Properties
        public Boolean Connected
        {
            get { return PLC.Connected; }
            private set
            {
                if (_Connected != value)
                {
                    _Connected = value;
                    OnPropertyChanged("Connected");
                }
            }
        }
        public IPAddress IP
        {
            get { return _IP; }
            set
            {
                if (_IP != value)
                {
                    _IP = value;
                    OnPropertyChanged("IP");
                }
            }
        }
        public ICommand ToggleConnection { get; private set; }
        public TagBoolean MaximumLevel { get; private set; }
        public TagBoolean MinimumLevel { get; private set; }
        public TagBoolean InletValve { get; private set; }
        public TagBoolean OutletValve { get; private set; }
        public TagSingle WaterTemperature { get; private set; }
        public TagInt16 WaterLevel { get; private set; }
        #endregion

        #region Private Properties
        private Automation.Modbus.ModbusTcpMaster PLC { get; set; }
        #endregion

        #region Private Methods
        private void Initialize()
        {
            ToggleConnection = new RelayCommand(param => ExecuteToggleConnection());
            InitializeTags();
            PLC = new Automation.Modbus.ModbusTcpMaster();
            PLC.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(PLC_PropertyChanged);
            AddTagsToPLC();
        }
        void PLC_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Connected")
            {
                Connected = PLC.Connected;
            }
        }
        private void ExecuteToggleConnection()
        {
            try
            {
                if (PLC.Connected)
                {
                    PLC.Disconnect();
                }
                else
                {
                    PLC.Connect(IP);
                }
            }
            catch (Exception exc)
            {
                 System.Windows.MessageBox.Show(exc.Message);
            }
        }
        private void AddTagsToPLC()
        {
            PLC.Add(MaximumLevel, 0);
            PLC.Add(MinimumLevel, 1);
            PLC.Add(InletValve, 2);
            PLC.Add(OutletValve, 3);
            PLC.Add(WaterTemperature, 0);
            PLC.Add(WaterLevel, 2);
        }
        private void InitializeTags()
        {
            MaximumLevel = new TagBoolean() { Name = "MaximumLevel" };
            MinimumLevel = new TagBoolean() { Name = "MinimumLevel" };
            InletValve = new TagBoolean() { Name = "InletValve" };
            OutletValve = new TagBoolean() { Name = "OutletValve" };
            WaterTemperature = new TagSingle() { Name = "WaterTemperature" };
            WaterLevel = new TagInt16() { Name = "WaterLevel" };
        }
        #endregion
    }
}
